﻿using DoNetDrive.Core.Command;
using DoNetDrive.Core.Connector.UDP;
using DoNetDrive.Core.Connector;
using DoNetDrive.Core;
using DotNetty.Buffers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UDPAgency
{

    /// <summary>
    /// 转发端 -- 下端
    /// </summary>
    internal class IORemoteHandle : INRequestHandle
    {
        private Random mMyRnd = new Random();
        ConnectorAllocator Allocator;
        private List<DoNetDrive.Core.Connector.TCPClient.TCPClientDetail> mAgencyMap;

        private string mLocalIP;
        private int mLocalPort;
        private UDPAgenncyOption _Option;
        public IORemoteHandle(List<DoNetDrive.Core.Connector.TCPClient.TCPClientDetail> AgencyMap,
            string sLocalIP, int iLocalPort,UDPAgenncyOption option)
        {
            mLocalIP = sLocalIP;
            mLocalPort = iLocalPort;
            mAgencyMap = AgencyMap;
            Allocator = ConnectorAllocator.GetAllocator();
            _Option = option;
        }

        public void Dispose()
        {
            Allocator = null;
            mAgencyMap = null;
        }

        public void DisposeRequest(INConnector connector, IByteBuffer msg)
        {//接收

            int ilen = msg.ReadableBytes;
            byte[] buf = new byte[ilen];
            msg.ReadBytes(buf);
            int iCount = mAgencyMap.Count;
            for (int i = 0; i < iCount; i++)
            {
                var map = mAgencyMap[i];
                var obuf = UnpooledByteBufferAllocator.Default.Buffer(ilen);
                obuf.WriteBytes(buf);

                var udp = new UDPClientDetail(map.Addr, map.Port, mLocalIP, mLocalPort);
                var cnl = Allocator.GetConnector(udp);
                if (cnl != null)
                {
                    if (_Option.UserPacketLose)
                    {
                        if (mMyRnd.Next(1000) > _Option.PacketLoseNum)
                        {
                            //Trace.WriteLine($"设备端回包 0x{ByteBufferUtil.HexDump(obuf).ToUpper()}");
                            cnl.WriteByteBuf(obuf);
                        }
                        else
                        {
                            //Trace.WriteLine($"设备端回包  强制丢弃 {_Option.LosePacketCount} 0x{ByteBufferUtil.HexDump(obuf).ToUpper()}");
                            _Option.AddLosePacketCount();
                        }
                    }
                    else
                    {
                        //Trace.WriteLine($"设备端回包 0x{ByteBufferUtil.HexDump(obuf).ToUpper()}");
                        cnl.WriteByteBuf(obuf);
                        
                    }


                }
                //var dtl = new ByteCommandDetail(new UDPClientDetail(map.RemoteHost, map.Port, mLocalIP, mLocalPort));

                //var cmd = new ByteCommand(dtl, new ByteCommandParameter(obuf));

                //Allocator.AddCommand(cmd);
            }
        }

        public void DisposeResponse(INConnector connector, IByteBuffer msg)
        {//发送


            //throw new NotImplementedException();
        }
    }
}
